/*
	*********************************
				SF2D Engine
	*********************************
	Movie Player that is used to play
	cutscenes in the engine

	By Julian Williams
	August 25, 2010
*/

#include <SFML/Graphics.hpp>

#include "helper.h"
#include "movie_player.h"









MoviePlayer movieManager;


MoviePlayer::MoviePlayer(void)
{
//Load Pointerz
	mgr = new TheoraVideoManager();
	iface_factory = new OpenAL_AudioInterfaceFactory();
	mgr->setAudioInterfaceFactory(iface_factory);
}


//destroy the manager pointer and 
//Nullify it, clean things up
MoviePlayer::~MoviePlayer(void)
{
//	mgr->destroyVideoClip( clip );
	
	delete iface_factory;
	delete mgr;
}


//Load cutscene from file
bool MoviePlayer::playCutscene( sf::RenderWindow* rendow, const std::string& file_location, sf::Key::Code escKey, bool player_control)
{

//Load the video
	MovieClip * cutscene = loadClip( file_location );

//Play it
	bool result = playCutscene(rendow, cutscene, escKey, player_control);

//now get rid of video
	destroyClip( cutscene );

	return result;

}//EoF



//Play fullscreened Cutscene
bool MoviePlayer::playCutscene(sf::RenderWindow *rendow, MovieClip *cutscene, sf::Key::Code escKey, bool player_control)
{
	
	//if cutscene we tried to load isn't valid, exit right meow
	if(!cutscene->isValid() ) { return false; }

	//Control rectangle info
	
		const int rect_height = 40;
		const int rect_alpha = 100;

		sf::Shape empty_bar   = sf::Shape::Rectangle(0, rendow->GetHeight()-rect_height, rendow->GetWidth(), rect_height, sf::Color(0,0,0,50), 2, sf::Color::White);
		
	//hide the cursor	
	if(!player_control)
	{	
		rendow->ShowMouseCursor(true);
	}

	bool run_cutscene = true;

	cutscene->Loop(false);
	cutscene->SetOrigin(0,0);
	cutscene->SetPosition(0, 0);

	//Mouse position
	sf::Vector2f mouse_pos;
	

	while (run_cutscene)
     {
		 // Process events
         sf::Event Event;
         while (rendow->GetEvent(Event))
         {
			 //Exit if the close button is pressed
			  if (Event.Type == sf::Event::Closed)
			 {
				 run_cutscene = false;
				 rendow->Close();
			 }


			   
			  //if user is allowd to control the video, make it so!
			 if(player_control)
			 {
			  //if the player has control of the video sequence, then let him seek/pause stuff
				if (Event.Type == sf::Event::MouseButtonPressed && Event.MouseButton.Button == sf::Mouse::Left)
				 {
				  
						 mouse_pos = rendow->ConvertCoords( rendow->GetInput().GetMouseX(), rendow->GetInput().GetMouseY() );
		 
						if( mouse_pos.y > rendow->GetHeight()-rect_height)
						{
							//Do some fancy frame seekage

							//I Sacrafice accuracy by using an int, to prevent frame/sound buffer skipping,
							//check out the original av player example of the Theora Playback Library,
							//you'll see what i mean, Totally worth it!
							int seek_location = (mouse_pos.x/rendow->GetWidth()) * cutscene->clip->getDuration();
							float seek_num = (seek_location > 0.1) ? seek_location : 0.1;

							cutscene->clip->seek(seek_num);
							//cutscene->clip->seek((mouse_pos.x/rendow->GetWidth())*cutscene->clip->getDuration());
						}
				 }

					//Pause the video
					if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Space) 
					{
						cutscene->togglePause();
					}
			 }
			  

			 if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == escKey) 
			 {
				 run_cutscene = false;
			 }

		 }//End of Events
	
		 
		 //Update images and sound
		 cutscene->Update( rendow->GetFrameTime() );
		 //Fullscreen this bad boy
		 cutscene->Resize(rendow->GetWidth(), rendow->GetHeight());

		  //if finsished, exit cutscene
		 if(cutscene->isFinished())
		 {
			 run_cutscene = false;
		 }




		


		 //Draw the cutscenes
		 rendow->Clear();
		 //Draw video yay!
			cutscene->Draw(rendow);
		//if Player has control, draw the track bar
			if(player_control)
			{
					//Draw outline of trackbar
					rendow->Draw(empty_bar);

					//Create and draw the actual trackbar, based on video position
					float rect_x = cutscene->clip->getTimePosition() / cutscene->clip->getDuration();
					sf::Shape track_bar   = sf::Shape::Rectangle(0, rendow->GetHeight()-rect_height, rendow->GetWidth()*rect_x, rect_height, sf::Color::White, 1, sf::Color::White);
					track_bar.SetColor(sf::Color(255,255,255, rect_alpha));
					rendow->Draw(track_bar);
			}

		 rendow->Display();
		
	}//End ov While loop


	return cutscene->isFinished();
}//EoF



//Load Movie clip from location
//(will add function to load from memory later

MovieClip* MoviePlayer::loadClip( const std::string& clip_location )
{
	MovieClip * newClip = new MovieClip(mgr);
	
	newClip->successfully_loaded = true;

    newClip->clip = mgr->createVideoClip( clip_location, TH_RGBA );
	if(newClip->clip == NULL)
	{
		std::cout << "[CUTSCENE] - Clip: " << clip_location.c_str() << " failed to load.\n";
		newClip->successfully_loaded = false;
	}

	return newClip;
}//EoF


//Function to Destroy a loaded movie clip
void MoviePlayer::destroyClip(MovieClip *movieClip)
{

	mgr->destroyVideoClip( movieClip->clip );
	//delete movieClip->clip;
	//movieClip->clip = NULL;
}

/*
void MoviePlayer::Update(float time_update)
{
	if (started)
	{
		// let's wait until the system caches up a few frames on startup
		if (clip->getNumReadyFrames() < clip->getNumPrecachedFrames()*0.5f)
			return;
		started=0;
	}

	mgr->update(time_update);
}//EoF



void MoviePlayer::Draw( sf::RenderWindow *rendow, bool repeat)
{
	TheoraVideoFrame* f = clip->getNextFrame();

	clip->setAutoRestart(repeat);

	if (f)
	{
		current_frame.LoadFromPixels(f->getWidth(), f->getHeight(), f->getBuffer());
	//	current_frame.UpdatePixels(f->getBuffer(), sf::IntRect(0, 0, f->getWidth(), f->getHeight()));
		current_frame.SetSmooth(false);

		SetImage(current_frame);

		clip->popFrame();
	}


	rendow->Draw(*this);
	

}//EoF



void MoviePlayer::TogglePause()
{
	if (clip->isPaused())
	{
		clip->play();
	}
	else
	{
		clip->pause(); 
	}
}//EoF
*/